/**
 * @file bmi270.h
 * @brief BMI270 6轴IMU驱动头文件
 *
 * BMI270是Bosch的单芯片6轴IMU，集成了3轴加速度计和3轴陀螺仪
 *
 * 硬件连接：
 *   - SPI3: PB3(SCK), PB4(MISO), PD6(MOSI)
 *   - CS: PA15
 *   - INT: PB7 (数据就绪中断)
 *
 * SPI配置：
 *   - 时钟源: PLL2_P (96MHz)
 *   - SPI速率: 12MHz (96MHz/8)
 *   - 模式: Mode 3 (CPOL=1, CPHA=1)
 *
 * 特性：
 *   - Chip ID: 0x24
 *   - 加速度计范围: ±2g, ±4g, ±8g, ±16g
 *   - 陀螺仪范围: ±125dps, ±250dps, ±500dps, ±1000dps, ±2000dps
 *   - 采样率: 最高1600Hz
 *   - FIFO: 1024字节
 */

#ifndef __BMI270_H
#define __BMI270_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/* BMI270寄存器地址 */
#define BMI270_CHIP_ID              0x00
#define BMI270_ERR_REG              0x02
#define BMI270_STATUS               0x03

#define BMI270_ACC_DATA_X_LSB       0x0C
#define BMI270_ACC_DATA_X_MSB       0x0D
#define BMI270_ACC_DATA_Y_LSB       0x0E
#define BMI270_ACC_DATA_Y_MSB       0x0F
#define BMI270_ACC_DATA_Z_LSB       0x10
#define BMI270_ACC_DATA_Z_MSB       0x11

#define BMI270_GYR_DATA_X_LSB       0x12
#define BMI270_GYR_DATA_X_MSB       0x13
#define BMI270_GYR_DATA_Y_LSB       0x14
#define BMI270_GYR_DATA_Y_MSB       0x15
#define BMI270_GYR_DATA_Z_LSB       0x16
#define BMI270_GYR_DATA_Z_MSB       0x17

#define BMI270_INTERNAL_STATUS      0x21
#define BMI270_TEMP_MSB             0x22
#define BMI270_TEMP_LSB             0x23

#define BMI270_FIFO_LENGTH_0        0x24
#define BMI270_FIFO_LENGTH_1        0x25
#define BMI270_FIFO_DATA            0x26

#define BMI270_ACC_CONF             0x40
#define BMI270_ACC_RANGE            0x41
#define BMI270_GYR_CONF             0x42
#define BMI270_GYR_RANGE            0x43

#define BMI270_FIFO_DOWNS           0x45
#define BMI270_FIFO_WTM_0           0x46
#define BMI270_FIFO_WTM_1           0x47
#define BMI270_FIFO_CONFIG_0        0x48
#define BMI270_FIFO_CONFIG_1        0x49

#define BMI270_INT1_IO_CTRL         0x53
#define BMI270_INT_MAP_DATA         0x58
#define BMI270_INIT_CTRL            0x59
#define BMI270_INIT_DATA            0x5E

#define BMI270_PWR_CONF             0x7C
#define BMI270_PWR_CTRL             0x7D
#define BMI270_CMD                  0x7E

/* BMI270常量 */
#define BMI270_CHIP_ID_VALUE        0x24
#define BMI270_SOFT_RESET_CMD       0xB6

/* 加速度计配置 */
#define BMI270_ACC_RANGE_2G         0x00
#define BMI270_ACC_RANGE_4G         0x01
#define BMI270_ACC_RANGE_8G         0x02
#define BMI270_ACC_RANGE_16G        0x03

#define BMI270_ACC_ODR_1600HZ       0x0C  /* 1600Hz */
#define BMI270_ACC_BWP_NORMAL       0xA0  /* Normal mode */

/* 陀螺仪配置 */
#define BMI270_GYR_RANGE_125DPS     0x04
#define BMI270_GYR_RANGE_250DPS     0x03
#define BMI270_GYR_RANGE_500DPS     0x02
#define BMI270_GYR_RANGE_1000DPS    0x01
#define BMI270_GYR_RANGE_2000DPS    0x00

#define BMI270_GYR_ODR_1600HZ       0x0C  /* 1600Hz: Bit3 | Bit2 */
#define BMI270_GYR_BWP_NORMAL       0xE0  /* Normal mode: Bit7(flt_hp) | Bit6(noise_hp) | Bit5(flt_mode_normal) */

/* 电源控制 */
#define BMI270_PWR_CTRL_ACC_EN      0x04
#define BMI270_PWR_CTRL_GYR_EN      0x02
#define BMI270_PWR_CTRL_TEMP_EN     0x08

/* FIFO配置 */
#define BMI270_FIFO_SIZE            1024
#define BMI270_FIFO_MAX_SAMPLES     32   /* 最大批量读取样本数 */

/* INT1引脚配置位 (INT1_IO_CTRL寄存器) */
#define BMI270_INT1_IN              0x10  /* Bit4: INT1输入使能 */
#define BMI270_INT1_OUT             0x08  /* Bit3: INT1输出使能 */
#define BMI270_INT1_OD              0x04  /* Bit2: INT1开漏输出 (0=推挽) */
#define BMI270_INT1_LVL             0x02  /* Bit1: INT1电平 (0=低电平有效, 1=高电平有效) */

/* INT映射位 (INT_MAP_DATA寄存器) */
#define BMI270_INT2_DRDY            0x40  /* Bit6: INT2数据就绪中断 */
#define BMI270_INT2_FWM             0x20  /* Bit5: INT2 FIFO水印中断 */
#define BMI270_INT2_FFULL           0x10  /* Bit4: INT2 FIFO满中断 */
#define BMI270_INT1_DRDY            0x04  /* Bit2: INT1数据就绪中断 */
#define BMI270_INT1_FWM             0x02  /* Bit1: INT1 FIFO水印中断 */
#define BMI270_INT1_FFULL           0x01  /* Bit0: INT1 FIFO满中断 */

/* FIFO帧头 */
#define BMI270_FIFO_HEADER_ACC      0x84  /* 加速度计帧 */
#define BMI270_FIFO_HEADER_GYR      0x88  /* 陀螺仪帧 */
#define BMI270_FIFO_HEADER_ACC_GYR  0x8C  /* 加速度计+陀螺仪组合帧 (0x84 | 0x88) */
#define BMI270_FIFO_HEADER_SKIP     0x40  /* 跳过帧 */
#define BMI270_FIFO_HEADER_TIME     0x44  /* 时间帧 */
#define BMI270_FIFO_HEADER_CONFIG   0x48  /* 配置帧 */
#define BMI270_FIFO_HEADER_DROP     0x50  /* 丢弃帧 */
#define BMI270_FIFO_HEADER_MASK     0xFC  /* 帧头掩码（忽略INT状态位） */

/* 数据转换系数 */
#define BMI270_ACC_SCALE_16G        (16.0f / 32768.0f * 9.80665f)  /* ±16g → m/s² */
#define BMI270_GYR_SCALE_2000DPS    (2000.0f / 32768.0f * 0.017453292f)  /* ±2000dps → rad/s */
#define BMI270_TEMP_SCALE           (1.0f / 512.0f)  /* 温度转换系数 */
#define BMI270_TEMP_OFFSET          (23.0f)          /* 温度偏移 */

/* BMI270数据结构 */
typedef struct {
    float accel_x;  /* 加速度X轴 (m/s²) */
    float accel_y;  /* 加速度Y轴 (m/s²) */
    float accel_z;  /* 加速度Z轴 (m/s²) */
    float gyro_x;   /* 陀螺仪X轴 (rad/s) */
    float gyro_y;   /* 陀螺仪Y轴 (rad/s) */
    float gyro_z;   /* 陀螺仪Z轴 (rad/s) */
    float temperature; /* 温度 (°C) */
    uint64_t timestamp;
} BMI270_Data_t;

/* BMI270 FIFO数据结构 */
typedef struct {
    int16_t accel_x[BMI270_FIFO_MAX_SAMPLES];
    int16_t accel_y[BMI270_FIFO_MAX_SAMPLES];
    int16_t accel_z[BMI270_FIFO_MAX_SAMPLES];
    uint8_t accel_count;
    uint64_t accel_timestamp;
} BMI270_FIFO_AccelData_t;

typedef struct {
    int16_t gyro_x[BMI270_FIFO_MAX_SAMPLES];
    int16_t gyro_y[BMI270_FIFO_MAX_SAMPLES];
    int16_t gyro_z[BMI270_FIFO_MAX_SAMPLES];
    uint8_t gyro_count;
    uint64_t gyro_timestamp;
} BMI270_FIFO_GyroData_t;

/* 组合FIFO数据结构 - 同时包含加速度计和陀螺仪 */
typedef struct {
    BMI270_FIFO_AccelData_t accel;
    BMI270_FIFO_GyroData_t gyro;
} BMI270_FIFO_Data_t;

/* 寄存器配置结构 - 用于验证寄存器配置 */
typedef struct {
    uint8_t reg;         /* 寄存器地址 */
    uint8_t set_bits;    /* 应该设置的位 */
    uint8_t clear_bits;  /* 应该清除的位 */
} BMI270_RegisterConfig_t;

/* 错误统计结构 */
typedef struct {
    uint32_t bad_register_count;   /* 寄存器检查失败次数 */
    uint32_t bad_transfer_count;   /* SPI传输失败次数 */
    uint32_t fifo_empty_count;     /* FIFO为空次数 */
    uint32_t fifo_overflow_count;  /* FIFO溢出次数 */
    uint32_t fifo_reset_count;     /* FIFO复位次数 */
} BMI270_ErrorStats_t;

/* 函数声明 */
int BMI270_Init(void);
uint8_t BMI270_ReadChipID(void);
int BMI270_DebugInfo(char *debug_buf, int buf_size);  /* 详细调试信息 */
int BMI270_ReadData(BMI270_Data_t *data);
float BMI270_ReadTemperature(void);

/* FIFO函数 */
int BMI270_FIFO_Init(uint16_t watermark);
int BMI270_FIFO_Read(BMI270_FIFO_Data_t *fifo_data);  /* 新函数：同时读取加速度计和陀螺仪 */
int BMI270_FIFO_ReadAccel(BMI270_FIFO_AccelData_t *fifo_data);  /* 已弃用：请使用BMI270_FIFO_Read */
int BMI270_FIFO_ReadGyro(BMI270_FIFO_GyroData_t *fifo_data);    /* 已弃用：请使用BMI270_FIFO_Read */
int BMI270_FIFO_Reset(void);
uint16_t BMI270_FIFO_GetLength(void);

/* 优先级2：重要改进功能 */
int BMI270_RegisterCheck(const BMI270_RegisterConfig_t *reg_cfg);  /* 寄存器配置验证 */
int BMI270_CheckErrorRegister(void);                               /* 错误寄存器检测 */
int BMI270_UpdateTemperature(float *temperature);                  /* 温度读取 */
void BMI270_GetErrorStats(BMI270_ErrorStats_t *stats);             /* 获取错误统计 */
void BMI270_ResetErrorStats(void);                                 /* 重置错误统计 */

/* ========== 优先级3：高级功能 ========== */

/* 状态机枚举 - 模仿PX4设计 */
typedef enum {
    BMI270_STATE_RESET = 0,           /* 复位状态 */
    BMI270_STATE_WAIT_FOR_RESET,      /* 等待复位完成 */
    BMI270_STATE_MICROCODE_LOAD,      /* 加载微代码（配置文件） */
    BMI270_STATE_CONFIGURE,           /* 配置传感器 */
    BMI270_STATE_FIFO_READ,           /* FIFO读取状态（正常运行） */
} BMI270_State_t;

/* 状态机管理函数 */
int BMI270_Reset(void);                                            /* 软复位传感器 */
BMI270_State_t BMI270_GetState(void);                              /* 获取当前状态 */
int BMI270_StateMachine(void);                                     /* 状态机处理（每次调用推进状态） */

/* FIFO管理函数 */
int BMI270_FIFO_CheckOverflow(void);                               /* 检查FIFO溢出 */
int BMI270_FIFO_ForceReset(void);                                  /* 强制复位FIFO */

/* 失败计数和自动恢复 */
void BMI270_IncrementFailureCount(void);                           /* 增加失败计数 */
void BMI270_ResetFailureCount(void);                               /* 重置失败计数 */
uint32_t BMI270_GetFailureCount(void);                             /* 获取失败计数 */

#ifdef __cplusplus
}
#endif

#endif /* __BMI270_H */

